package com.aphrodite.io.sip.message;

import com.aphrodite.io.sip.address.NameAddress;
import com.aphrodite.io.sip.address.SipURL;
import com.aphrodite.io.sip.dialog.Dialog;
import com.aphrodite.io.sip.header.EventHeader;
import com.aphrodite.io.sip.header.ReferToHeader;
import com.aphrodite.io.sip.header.ReferredByHeader;
import com.aphrodite.io.sip.header.SubjectHeader;
import com.aphrodite.io.sip.provider.SipProvider;

/**
 * Class sipx.message.MessageFactory extends class
 * sip.message.BaseMessageFactory. <p /> MessageFactory is used to create SIP
 * messages (requests and responses). <br /> A valid SIP request sent by a UAC
 * MUST, at least, contain the following header fields: To, From, CSeq, Call-ID,
 * Max-Forwards, and Via; all of these header fields are mandatory in all SIP
 * requests. These sip header fields are the fundamental building blocks of a
 * SIP message, as they jointly provide for most of the critical message routing
 * services including the addressing of messages, the routing of responses,
 * limiting message propagation, ordering of messages, and the unique
 * identification of transactions. These header fields are in addition to the
 * mandatory request line, which contains the method, Request-URI, and SIP
 * version.
 */
public final class MessageFactory extends BaseMessageFactory {

	/** Creates a new MESSAGE request (RFC3428) */
	public static Message createMessageRequest(SipProvider sip_provider, NameAddress recipient, NameAddress from,
			String subject, String type, String body) {
		SipURL request_uri = recipient.getAddress();
		String callid = sip_provider.pickCallId();
		int cseq = SipProvider.pickInitialCSeq();
		String localtag = SipProvider.pickTag();
		// String branch=SipStack.pickBranch();
		Message req = createRequest(sip_provider, SipMethods.MESSAGE, request_uri, recipient, from, null, callid, cseq,
				localtag, null, null, null);
		if (subject != null)
			req.setSubjectHeader(new SubjectHeader(subject));
		req.setBody(type, body);
		return req;
	}

	/** Creates a new NOTIFY request (RFC3265) within a dialog */
	public static Message createNotifyRequest(Dialog dialog, String event, String id, String sipfragment) {
		Message req = createRequest(dialog, SipMethods.NOTIFY, null);
		req.removeExpiresHeader();
		req.setEventHeader(new EventHeader(event, id));
		req.setBody("message/sipfrag;version=2.0", sipfragment);
		return req;
	}

	/** Creates a new NOTIFY request (RFC3265) within a dialog */
	public static Message createNotifyRequest(Dialog dialog, String event, String id, String content_type, String body) {
		Message req = createRequest(dialog, SipMethods.NOTIFY, null);
		req.removeExpiresHeader();
		req.setEventHeader(new EventHeader(event, id));
		req.setBody(content_type, body);
		return req;
	}

	/**
	 * Creates a new REFER request (RFC3515) within a dialog
	 * <p>
	 * parameters: <br>
	 * - <i>refer_to</i> mandatory <br>
	 * - <i>referred_by</i> optional
	 */
	public static Message createReferRequest(Dialog dialog, NameAddress refer_to, NameAddress referred_by) {
		Message req = createRequest(dialog, SipMethods.REFER, null);
		req.setReferToHeader(new ReferToHeader(refer_to));
		if (referred_by != null)
			req.setReferredByHeader(new ReferredByHeader(referred_by));
		else
			req.setReferredByHeader(new ReferredByHeader(dialog.getLocalName()));
		return req;
	}

	/** Creates a new REFER request (RFC3515) */
	public static Message createReferRequest(SipProvider sip_provider, NameAddress recipient, NameAddress from,
			NameAddress contact, NameAddress refer_to/* , NameAddress referred_by */) {
		SipURL request_uri = recipient.getAddress();
		String callid = sip_provider.pickCallId();
		int cseq = SipProvider.pickInitialCSeq();
		String localtag = SipProvider.pickTag();
		// String branch=SipStack.pickBranch();
		Message req = createRequest(sip_provider, SipMethods.REFER, request_uri, recipient, from, contact, callid,
				cseq, localtag, null, null, null);
		req.setReferToHeader(new ReferToHeader(refer_to));
		// if (referred_by!=null) req.setReferredByHeader(new
		// ReferredByHeader(referred_by));
		req.setReferredByHeader(new ReferredByHeader(from));
		return req;
	}

	/**
	 * Creates a new SUBSCRIBE request (RFC3265) within a dialog (re-subscribe).
	 */
	public static Message createSubscribeRequest(Dialog dialog, String event, String id, String content_type,
			String body) {
		Message req = createRequest(dialog, SipMethods.SUBSCRIBE, null);
		req.setEventHeader(new EventHeader(event, id));
		req.setBody(content_type, body);
		return req;
	}

	/**
	 * Creates a new SUBSCRIBE request (RFC3265) out of any pre-existing
	 * dialogs.
	 */
	public static Message createSubscribeRequest(SipProvider sip_provider, SipURL recipient, NameAddress to,
			NameAddress from, NameAddress contact, String event, String id, String content_type, String body) {
		Message req = createRequest(sip_provider, SipMethods.SUBSCRIBE, recipient, to, from, contact, null);
		req.setEventHeader(new EventHeader(event, id));
		req.setBody(content_type, body);
		return req;
	}

}